﻿
using Castle.Core.Internal;
using Coldairarrow.Business.Interface;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.Interface;
using Coldairarrow.Util;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;

namespace Coldairarrow.Business.Interface
{
    public class Rep_InventoryStatisticsInterfaceBusiness : Interface_BaseBusiness, IJob_Business, ITransientDependency
    {
        public List<OL_FilterDTO> Filters;
        public Rep_InventoryStatisticsInterfaceBusiness()
        {
            this.InterfaceName = "1C库存总表";
            //获取字段的映射关系
            tableField = GetMapField("editRow");
            //索引字段
            Keys = GetKeys("editRow");
            indexFields.Add(Keys.Where(X => X.Type == "K").First().Field);
            //查询过滤条件
            Filters = new List<OL_FilterDTO>();


            //查询执行前的事件
            BeforeQueryEvent += InterfaceBusiness_BeforeQueryEvent;
            //查询执行中的事件
            OnQueryEvent += InterfaceBusiness_OnQueryEvent;
            //执行非查询请求中的事件
            OnNoQueryEvent += InterfaceBusiness_OnNoQueryEvent;

        }

        /// <summary>
        /// 执行非查询请求中时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="noQueryEventArgs"></param>
        private void InterfaceBusiness_OnNoQueryEvent(object sender, NoQueryEventArgs noQueryEventArgs)
        {
            //API请求是否成功
            noQueryEventArgs.Success = noQueryEventArgs.Result["success"].ToString().ToBool();
        }

        /// <summary>
        /// 查询执行前的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="queryEventArgs"></param>
        private void InterfaceBusiness_BeforeQueryEvent(object sender, QueryEventArgs queryEventArgs)
        {
            //执行查询前添加过滤条件
            if (queryEventArgs.Page.Filters.IsNullOrEmpty() && !Filters.IsNullOrEmpty())
            {
                queryEventArgs.Page.Filters = Filters;
            }

        }

        /// <summary>
        /// 查询执行中的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="queryEventArgs"></param>
        private void InterfaceBusiness_OnQueryEvent(object sender, QueryEventArgs queryEventArgs)
        {
            //是否查询完成
            if (queryEventArgs.Result["data"]["rows"].ToList().Count == 0)
            {
                queryEventArgs.Page.Complete = true;
            }
            //向总行中添加新的行
            queryEventArgs.Rows.AddRange(queryEventArgs.Result["data"]["rows"].ToList());
            //获取总页数
            queryEventArgs.Page.Total = queryEventArgs.Result["data"]["total"].ToString().ToInt();
            //获取查询成功标志
            queryEventArgs.Success = queryEventArgs.Result["success"].ToString().ToBool();
        }


        /// <summary>
        /// 执行增删改查业务
        /// </summary>
        public async void ExecuteInterface()
        {

            try
            {
                //数据库连接
                ConString = JsonSettingHelper.GetSetting("Database:BaseDb:ConnectionString");
                SqlDb = (SqlServerHelper)DbHelperFactory.GetDbHelper(EFCore.Sharding.DatabaseType.SqlServer, ConString);

                //获取此接口的所有API信息
                this.interfaceOption = SqlDb.GetListBySql<Base_InterfaceOption>(@$"SELECT * FROM  Base_InterfaceOption(NOLOCK) WHERE Name='{InterfaceName}' ");
                Base_InterfaceOption queryOption = this.interfaceOption.Where(o => o.OperateType == "getFilterRows").First();//查询API配置
                Base_InterfaceOption insertOption = this.interfaceOption.Where(o => o.OperateType == "addRow").First();//新增API配置
                Base_InterfaceOption upDateOption = this.interfaceOption.Where(o => o.OperateType == "editRow").First();//更行API配置
                Base_InterfaceOption deleteOption = this.interfaceOption.Where(o => o.OperateType == "deleteRow").First();//删除API配置

                var fDate = DateTime.Now.AddMonths(-queryOption.ExcInterval);

                List<Rep_InventoryStatistics> sourceData = new List<Rep_InventoryStatistics>();

                //获取1C库存表
                List<Rep_1CInventory> OC_inventory = SqlDb.GetListBySql<Rep_1CInventory>(@$"SELECT * FROM  SD_1C_Rep_1CInventory(NOLOCK)");

                //将库存数量按照顾物料分组统计
                OC_inventory.GroupBy(x => x.productNo).ForEach(x =>
                {
                    if (!x.Key.IsNullOrEmpty())
                    {
                        Rep_InventoryStatistics item = new Rep_InventoryStatistics();
                        var qty = x.Sum(x => x.qty);
                        item.qty = qty.ToString();
                        //item.productName = x.First().productName;
                        item.productNo = x.First().productNo;
                        item.id = item.productNo;
                        sourceData.Add(item);
                    }
                });
                //
                OC_inventory.Where(x => x.productNo.IsNullOrEmpty()).ForEach(x =>
                {
                    Rep_InventoryStatistics item = new Rep_InventoryStatistics();
                    item.qty = x.qty.ToString();
                    item.productName = x.productName;
                    item.id = x.productName;
                    sourceData.Add(item);

                });

                //获取金蝶的应收单列表
                AR_RECEIVABLEInterfaceBusiness KD_aR_RECEIVABLE = new AR_RECEIVABLEInterfaceBusiness();
                //查询条件
                KD_aR_RECEIVABLE.Filters.Clear();
                KD_aR_RECEIVABLE.Filters.Add(
              new OL_FilterDTO() { ControlId = "66b313d70604789daa621b63", DataType = 15, SpliceType = 1, FilterType = 14, Value = fDate.ToString("yyyy-MM-dd") }//过滤日期
          );
                KD_aR_RECEIVABLE.Filters.Add(
              new OL_FilterDTO() { ControlId = "66b313d70604789daa621b6a", DataType = 2, SpliceType = 1, FilterType = 2, Value = "1.1251" }//客户编号过滤
          );
                KD_aR_RECEIVABLE.Filters.Add(
              new OL_FilterDTO() { ControlId = "66b313d70604789daa621b6d", DataType = 2, SpliceType = 1, FilterType = 2, Value = "暂估应收" }//立账类型
          );
                KD_aR_RECEIVABLE.Filters.Add(
              new OL_FilterDTO() { ControlId = "66b313d70604789daa621b71", DataType = 6, SpliceType = 1, FilterType = 13, Value = "0" }//数量大于0
          );
                List<V_AR_RECEIVABLE> KD_receivableList = await KD_aR_RECEIVABLE.QueryAsync<V_AR_RECEIVABLE>(KD_aR_RECEIVABLE.queryOption, KD_aR_RECEIVABLE.tableField, KD_aR_RECEIVABLE.SqlDb);


                //获取1C的付款单(采购入库)列表
                PurchaseInvInterfaceBusiness OC_purchaseIn = new PurchaseInvInterfaceBusiness();
                OC_purchaseIn.Filters.Clear();
                OC_purchaseIn.Filters.Add(
                //13:>,14>=15:<,16<=
                new OL_FilterDTO() { ControlId = "67c50f3a9e0bc69bf125cfcc", DataType = 15, SpliceType = 1, FilterType = 14, Value = fDate.ToString("yyyy-MM-dd") }//过滤日期
            );
                //    OC_purchaseIn.Filters.Add(
                //    //13:>,14>=15:<,16<=
                //    new OL_FilterDTO() { ControlId = "67c510519e0bc69bf125d5ff", DataType = 2, SpliceType = 1, FilterType = 1, Value = "SN" }//发票编号包含SN的项
                //);
                List<PurchaseInv> OC_purchaseInvList = await OC_purchaseIn.QueryAsync<PurchaseInv>(OC_purchaseIn.queryOption, OC_purchaseIn.tableField, OC_purchaseIn.SqlDb);
                List<string> repeatItem = new List<string>();
                //在途数量及
                KD_receivableList.ForEach(rec =>
                {
                    if (rec.FBILLNO == "SN1240617001" && rec.FNUMBER == "CB.002.0224.0003")
                    {
                        var s = "";
                    }
                    //获取发票号相同，物料编号相同的项
                    if (rec.FBILLNO == "SN1240605001")
                    {
                        var s = "";
                    }
                    if (!repeatItem.Contains(rec.RowId) && rec.IsCheck != "1")
                    {

                        var KD_FBILLNO = rec.FBILLNO.Contains("SN") && rec.FBILLNO.Length <= 12 || !rec.FBILLNO.Contains("SN") ? rec.FBILLNO : rec.FBILLNO.Substring(0, 12);
                        var OC_purInv = OC_purchaseInvList.Where(y => y.invNo.Contains(KD_FBILLNO) && y.productNo.Contains(rec.FNUMBER));
                        List<Rep_InventoryStatistics> OC_Inv = new List<Rep_InventoryStatistics>();
                        //如果存在入库项，用入库项的物料编码去查询库存
                        if (!OC_purInv.IsNullOrEmpty() && OC_purInv.Count() > 0)
                        {
                            OC_purInv.ForEach(x =>
                            {
                                var inv = sourceData.Where(z => z.productNo == x.productNo);
                                if (inv.Count() > 0 && !inv.IsNullOrEmpty()) OC_Inv.AddRange(inv);
                            });
                        }
                        //如果不存在入库项，用金蝶应收单的编码去查询库存
                        else
                        {
                            var inv = sourceData.Where(z => z.productNo == rec.FNUMBER);
                            var inv1 = sourceData.Where(z => z.productNo.IsNullOrEmpty() ? false : z.productNo.Contains(rec.FNUMBER));
                            if (!inv.IsNullOrEmpty() && inv.Count() > 0)
                            {
                                OC_Inv.AddRange(inv);
                            }
                            else
                            {
                                OC_Inv.AddRange(inv1);
                            }

                        }


                        //如果存在入库项，能查询到物料库存
                        if (!OC_purInv.IsNullOrEmpty() && OC_purInv.Count() > 0 && !OC_Inv.IsNullOrEmpty() && OC_Inv.Count() > 0)
                        {
                            //已入库的数量
                            var qty = OC_purInv.Sum(x => x.qty.ToDouble());
                            //在途的数量
                            var qty_ = rec.FPRICEQTY.ToDouble() - qty;
                            //在途大于0
                            if (qty_ > 0)
                            {
                                var invItem = OC_Inv.First();
                                //设置在途
                                invItem.qtyIntransit = (invItem.qtyIntransit.ToDouble() + qty_).ToString();
                                //设置在途订单
                                invItem.orderIntransit = invItem.orderIntransit.IsNullOrEmpty() ? rec.RowId : invItem.orderIntransit + "," + rec.RowId;
                            }
                            else if (qty_ < 0)
                            {
                                var item = KD_receivableList.Where(x => x.FBILLNO.Contains(KD_FBILLNO) && x.FNUMBER == rec.FNUMBER);
                                if (!item.IsNullOrEmpty() && item.Count() > 1)
                                {
                                    qty_ = item.Sum(x => x.FPRICEQTY.ToDouble()) - qty;

                                    if (qty_ > 0)
                                    {
                                        var invItem = OC_Inv.First();
                                        //设置在途
                                        invItem.qtyIntransit = (invItem.qtyIntransit.ToDouble() + qty_).ToString();
                                        //设置在途订单
                                        //item.Where(x => x.FPRICEQTY.ToDouble() == OC_purInv.qty);
                                        var first = item.OrderBy(x => x.FPRICEQTY.ToDouble()).First();
                                        invItem.orderIntransit = invItem.orderIntransit.IsNullOrEmpty() ? first.RowId : invItem.orderIntransit + "," + first.RowId;

                                    }
                                    //将相同的项移除后续有可能会重复
                                    item.ForEach(x => repeatItem.Add(x.RowId));
                                }
                            }
                        }
                        //如果存在入库项，不能查询到物料库存，已出库，无需操作

                        //如果不存在入库项，能查询到物料库存
                        else if (OC_purInv.IsNullOrEmpty() && !OC_Inv.IsNullOrEmpty() && OC_Inv.Count() > 0)
                        {
                            var invItem = OC_Inv.First();
                            //设置在途
                            invItem.qtyIntransit = (invItem.qtyIntransit.ToDouble() + rec.FPRICEQTY.ToDouble()).ToString();
                            //设置在途订单
                            invItem.orderIntransit = invItem.orderIntransit.IsNullOrEmpty() ? rec.RowId : invItem.orderIntransit + "," + rec.RowId;

                        }
                        //如果不存在入库项，不能查询到物料库存
                        else if (OC_purInv.IsNullOrEmpty() && OC_Inv.IsNullOrEmpty())
                        {
                            Rep_InventoryStatistics item = new Rep_InventoryStatistics();
                            item.qtyIntransit = rec.FPRICEQTY;
                            //item.productName = ;
                            item.productNo = rec.FNUMBER;
                            //设置在途订单
                            item.orderIntransit = item.orderIntransit.IsNullOrEmpty() ? rec.RowId : item.orderIntransit + "," + rec.RowId;
                            sourceData.Add(item);
                        }

                    }
                });

                //id赋值
                sourceData.ForEach(x =>
                {
                    x.id = x.productNo + x.productName;
                    x.orderIntransit = x.orderIntransit.IsNullOrEmpty() ? "" : string.Join(",", x.orderIntransit.Split(',').OrderBy(x => x));

                });


                //获取目标数据
                List<Rep_InventoryStatistics> targetData = new List<Rep_InventoryStatistics>();//目标据集合
                                                                                               //var fDate = sourceData.OrderBy(x => x.date.ToDateTime()).First().date.ToDateTime().ToString("yyyy-MM-dd");

                //var fDate = sourceData.OrderBy(x => x.date.ToDateTime()).First().date.ToDateTime().ToString("yyyy-MM-dd");
                Filters.Clear();
                Filters.Add(
                //13:>,14>=15:<,16<=
                new OL_FilterDTO() { ControlId = "", DataType = 15, SpliceType = 1, FilterType = 14, Value = "" }//FDATE字段过滤日开
            );
                targetData = await QueryAsync<Rep_InventoryStatistics>(queryOption, tableField, SqlDb);

                foreach (var item1 in targetData)
                {
                    //将关联表的ID拼接成对应的格式
                    List<string> table = item1.orderIntransit.ToObject<List<string>>();
                    var idList = table.OrderBy(x => x);
                    item1.orderIntransit = string.Join(",", idList);

                    foreach (var item2 in sourceData)
                    {
                        if (item1.id == item2.id) item2.productName = item1.productName;
                    }
                }

                if (this.State > 0 && sourceData.Count > 0)
                {
                    //更新
                    #region
                    List<Rep_InventoryStatistics> updataItem = sourceData.Intersect(targetData, new ComparerFromKeys<Rep_InventoryStatistics>(Keys, "RowId")).ToList();//获取交集(更新项)
                    List<OL_RowDTO> updataData = ConvertOL_Row(updataItem, tableField);//需要更新的数据集合
                    ExecuteNoQuery<OL_RowDTO>(updataData, upDateOption, SqlDb);//执行更新
                    #endregion

                    //新增
                    #region
                    List<Rep_InventoryStatistics> insertItem = sourceData.Except(targetData, new ComparerFromKey<Rep_InventoryStatistics>(indexFields.First(), "RowId")).ToList();//获取源数据对目标数据的差集(新增项)
                    List<OL_RowDTO> insertData = ConvertOL_Row(insertItem, tableField);//需要新增的数据集合
                    ExecuteNoQuery<OL_RowDTO>(insertData, insertOption, SqlDb);//执行插入行
                    #endregion

                    //删除
                    #region
                    List<Rep_InventoryStatistics> deleteItem = targetData.Except(sourceData, new ComparerFromKey<Rep_InventoryStatistics>(indexFields.First(), "RowId")).ToList();//获取目标数对据源数据的差集(删除项)
                    List<OL_RowDTO> deleteData = ConvertOL_Row(deleteItem, tableField);//需要删除的数据集合
                    ExecuteNoQuery<OL_RowDTO>(deleteData, deleteOption, SqlDb);//执行删除行
                    #endregion
                }
            }


            catch (Exception ex)
            {
                AddLog(SqlDb, ex.Message, InterfaceName, "erro", "");
            }
        }

        /// <summary>
        /// 将源数据根据字典映射关系转换成OL_RowDTO
        /// </summary>
        /// <typeparam name="T">源数据</typeparam>
        /// <param name="sourceData">源数据</param>
        /// <param name="map">Key为目标字段名称，Value为源字段名称</param>
        /// <returns></returns>
        public List<OL_RowDTO> ConvertOL_Row<T>(List<T> sourceData, Dictionary<string, string> map)
        {
            List<OL_RowDTO> list = new List<OL_RowDTO>();
            object rowId;
            foreach (var item in sourceData)
            {
                rowId = item.GetPropertyValue("RowId");
                //需要新增的数据
                OL_RowDTO row = new OL_RowDTO() { RowId = rowId.IsNullOrEmpty() ? null : rowId.ToString(), Controls = new List<Control>() };
                foreach (var c in map)
                {
                    //获取字段的键值做判断
                    var field = Keys.Where(x => x.TField == c.Key).ToList();
                    string isKey = "";
                    if (field.Count > 0) isKey = field.First().Type;
                    //判断对象的字段是否存在
                    if (item.ContainsProperty(c.Value) && isKey != "N")
                    {
                        //存在则添加数据
                        row.Controls.Add(new Control() { ControlId = c.Key, Value = item.GetPropertyValue(c.Value) });
                    }
                }
                list.Add(row);
            }
            return list;
        }

        /// <summary>
        /// 任务
        /// </summary>
        public void Job()
        {
            ExecuteInterface();
        }
    }

}
